import { LogHelper } from "../utils/logHelper";
import { CreepsConfig,SpecialCreeps } from '../game/global';

Creep.prototype.run = function():void {
  
  let task:ICreepTask | undefined = undefined;
  if(this.memory.bornRoom){
    // 基础爬虫任务分配
    if(!task){
      const controllerLevel = Game.rooms[this.memory.bornRoom].controller?.level;
      if(controllerLevel) {
        const config = CreepsConfig.find((c)=> c.controllerLevel === controllerLevel );
        if(config && config.creeps.length > 0){
          const creepConfig = config?.creeps.find((c) =>  c.role === this.memory.role );
          if(creepConfig){
            task = creepConfig.taskLogic;
          }
        }
      }
    }
    
    // 特殊爬虫任务分配
    if(!task){
      const specialCreepConfig = SpecialCreeps.find((creepConfig:any) => creepConfig.role === this.memory.role);
      if(specialCreepConfig){
        task = new specialCreepConfig.taskLogic();
      }
    }

    if(task){
      task.run(this);
    }
  }

}

/**
 * 简单对穿代码
 */
Creep.prototype.go = function(target: RoomPosition | { pos: RoomPosition }): CreepMoveReturnCode | -5 | -10 {
  let dest: RoomPosition = ('pos' in target) ? target.pos : target;

  if(!this.memory._go || 
    this.memory._go.dest.x !== dest.x || 
    this.memory._go.dest.y !== dest.y ||
    this.memory._go.dest.roomName !== dest.roomName ||
    this.memory._go.room !== this.room.name)
  {
    let findPath = this.pos.findPathTo(target);
    if(findPath.length !== 0){
      this.memory._go = { dest:dest,path:findPath,room:this.room.name };
    }
  }

  if(this.memory._go){
    // 判断前面是否挡了个creep
    const pathIndex = this.memory._go.path.findIndex((p) => p.x === this.pos.x && p.y === this.pos.y);
    if(pathIndex < this.memory._go.path.length && pathIndex !== -1){
      const nextPath = this.memory._go.path[pathIndex+1];
      const myPath = this.memory._go.path[pathIndex];
      if(nextPath && myPath){
        const nextCreep = this.room.find(FIND_MY_CREEPS)
          .find(c=> c.pos.x === nextPath.x && c.pos.y === nextPath.y);
        if(nextCreep) {
          let move = false;

          // 判断是否停留过久
          if(!nextCreep.memory._posStay) {
            nextCreep.memory._posStay = { pos:nextCreep.pos,tick:0 };
          }
          else {
            // 如果当前位置还是停留在之前记录的位置上并且超过了2tick，那么则交换位置
            if(nextCreep.memory._posStay.pos.x === nextCreep.pos.x && 
              nextCreep.memory._posStay.pos.y === nextCreep.pos.y &&
              nextCreep.memory._posStay.pos.roomName === nextCreep.pos.roomName)
            {
              if(nextCreep.memory._posStay.tick > 1){
                move = true;
              }
              else {
                nextCreep.memory._posStay.tick += 1;
              }
            }
            else {
              // 不在之前停留位置
              delete nextCreep.memory._posStay;
            }
          }

          if(move){
            if(nextCreep.memory.role !== 'harvesterSourc'){
              this.say('🔁');
              nextCreep.say('🔁');
              this.moveByPath(this.pos.findPathTo(nextCreep.pos));
              nextCreep.moveByPath(nextCreep.pos.findPathTo(this.pos));
            }
            else{
              this.moveTo(target);
            }
          }
        }
      }
    }

    let moveResult = this.moveByPath(this.memory._go.path);
    if (moveResult === OK) {
      // 如果移动成功，检查 creep 是否已经到达目标位置
      if (this.pos.isEqualTo(this.memory._go.dest)) {
        delete this.memory._go;
      }
    }
    else if(moveResult === ERR_NOT_FOUND){
      delete this.memory._go;
    }
    return moveResult;
  }

  return ERR_INVALID_ARGS;
}

Creep.prototype.findClosestPath = function(end:RoomPosition):RoomPosition[] | null{
  const options: PathFinderOpts = {
    plainCost: 2, // 走在平地上的成本
    swampCost: 10, // 走在沼泽上的成本
    roomCallback: (roomName: string) => {
      const room = Game.rooms[roomName];
      if (!room) return false;

      const costs = new PathFinder.CostMatrix();
      room.find(FIND_STRUCTURES).forEach((structure: Structure) => {
        if (structure.structureType === STRUCTURE_WALL) {
          // 绕开墙壁
          costs.set(structure.pos.x, structure.pos.y, 0xff);
        } 
        else if (structure.structureType === STRUCTURE_ROAD || structure.structureType === STRUCTURE_CONTAINER) {
          // 优先走在道路和容器上
          costs.set(structure.pos.x, structure.pos.y, 1);
        }
      });

      return costs;
    },
  };

  const path = PathFinder.search(this.pos, { pos: end, range: 1 }, options);

  if (path.path.length === 0) {
    return null; // 没有找到路径
  }

  return path.path;
}